<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Error Function Inverses</title>
<link rel="stylesheet" href="../../math.css" type="text/css">
<meta name="generator" content="DocBook XSL Stylesheets V1.79.1">
<link rel="home" href="../../index.html" title="Math Toolkit 4.2.0">
<link rel="up" href="../sf_erf.html" title="Error Functions">
<link rel="prev" href="error_function.html" title="Error Function erf and complement erfc">
<link rel="next" href="../sf_poly.html" title="Polynomials">
<meta name="viewport" content="width=device-width, initial-scale=1">
</head>
<body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF">
<table cellpadding="2" width="100%"><tr>
<td valign="top"><img alt="Boost C++ Libraries" width="277" height="86" src="../../../../../../boost.png"></td>
<td align="center"><a href="../../../../../../index.html">Home</a></td>
<td align="center"><a href="../../../../../../libs/libraries.htm">Libraries</a></td>
<td align="center"><a href="http://www.boost.org/users/people.html">People</a></td>
<td align="center"><a href="http://www.boost.org/users/faq.html">FAQ</a></td>
<td align="center"><a href="../../../../../../more/index.htm">More</a></td>
</tr></table>
<hr>
<div class="spirit-nav">
<a accesskey="p" href="error_function.html"><img src="../../../../../../doc/src/images/prev.png" alt="Prev"></a><a accesskey="u" href="../sf_erf.html"><img src="../../../../../../doc/src/images/up.png" alt="Up"></a><a accesskey="h" href="../../index.html"><img src="../../../../../../doc/src/images/home.png" alt="Home"></a><a accesskey="n" href="../sf_poly.html"><img src="../../../../../../doc/src/images/next.png" alt="Next"></a>
</div>
<div class="section">
<div class="titlepage"><div><div><h3 class="title">
<a name="math_toolkit.sf_erf.error_inv"></a><a class="link" href="error_inv.html" title="Error Function Inverses">Error Function Inverses</a>
</h3></div></div></div>
<h5>
<a name="math_toolkit.sf_erf.error_inv.h0"></a>
        <span class="phrase"><a name="math_toolkit.sf_erf.error_inv.synopsis"></a></span><a class="link" href="error_inv.html#math_toolkit.sf_erf.error_inv.synopsis">Synopsis</a>
      </h5>
<pre class="programlisting"><span class="preprocessor">#include</span> <span class="special">&lt;</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">math</span><span class="special">/</span><span class="identifier">special_functions</span><span class="special">/</span><span class="identifier">erf</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">&gt;</span>
</pre>
<pre class="programlisting"><span class="keyword">namespace</span> <span class="identifier">boost</span><span class="special">{</span> <span class="keyword">namespace</span> <span class="identifier">math</span><span class="special">{</span>

<span class="keyword">template</span> <span class="special">&lt;</span><span class="keyword">class</span> <span class="identifier">T</span><span class="special">&gt;</span>
<a class="link" href="../result_type.html" title="Calculation of the Type of the Result"><span class="emphasis"><em>calculated-result-type</em></span></a> <span class="identifier">erf_inv</span><span class="special">(</span><span class="identifier">T</span> <span class="identifier">p</span><span class="special">);</span>

<span class="keyword">template</span> <span class="special">&lt;</span><span class="keyword">class</span> <span class="identifier">T</span><span class="special">,</span> <span class="keyword">class</span> <a class="link" href="../../policy.html" title="Chapter 22. Policies: Controlling Precision, Error Handling etc">Policy</a><span class="special">&gt;</span>
<a class="link" href="../result_type.html" title="Calculation of the Type of the Result"><span class="emphasis"><em>calculated-result-type</em></span></a> <span class="identifier">erf_inv</span><span class="special">(</span><span class="identifier">T</span> <span class="identifier">p</span><span class="special">,</span> <span class="keyword">const</span> <a class="link" href="../../policy.html" title="Chapter 22. Policies: Controlling Precision, Error Handling etc">Policy</a><span class="special">&amp;);</span>

<span class="keyword">template</span> <span class="special">&lt;</span><span class="keyword">class</span> <span class="identifier">T</span><span class="special">&gt;</span>
<a class="link" href="../result_type.html" title="Calculation of the Type of the Result"><span class="emphasis"><em>calculated-result-type</em></span></a> <span class="identifier">erfc_inv</span><span class="special">(</span><span class="identifier">T</span> <span class="identifier">p</span><span class="special">);</span>

<span class="keyword">template</span> <span class="special">&lt;</span><span class="keyword">class</span> <span class="identifier">T</span><span class="special">,</span> <span class="keyword">class</span> <a class="link" href="../../policy.html" title="Chapter 22. Policies: Controlling Precision, Error Handling etc">Policy</a><span class="special">&gt;</span>
<a class="link" href="../result_type.html" title="Calculation of the Type of the Result"><span class="emphasis"><em>calculated-result-type</em></span></a> <span class="identifier">erfc_inv</span><span class="special">(</span><span class="identifier">T</span> <span class="identifier">p</span><span class="special">,</span> <span class="keyword">const</span> <a class="link" href="../../policy.html" title="Chapter 22. Policies: Controlling Precision, Error Handling etc">Policy</a><span class="special">&amp;);</span>

<span class="special">}}</span> <span class="comment">// namespaces</span>
</pre>
<p>
        The return type of these functions is computed using the <a class="link" href="../result_type.html" title="Calculation of the Type of the Result"><span class="emphasis"><em>result
        type calculation rules</em></span></a>: the return type is <code class="computeroutput"><span class="keyword">double</span></code> if T is an integer type, and T otherwise.
      </p>
<p>
        The final <a class="link" href="../../policy.html" title="Chapter 22. Policies: Controlling Precision, Error Handling etc">Policy</a> argument is optional and can
        be used to control the behaviour of the function: how it handles errors,
        what level of precision to use etc. Refer to the <a class="link" href="../../policy.html" title="Chapter 22. Policies: Controlling Precision, Error Handling etc">policy
        documentation for more details</a>.
      </p>
<h5>
<a name="math_toolkit.sf_erf.error_inv.h1"></a>
        <span class="phrase"><a name="math_toolkit.sf_erf.error_inv.description"></a></span><a class="link" href="error_inv.html#math_toolkit.sf_erf.error_inv.description">Description</a>
      </h5>
<pre class="programlisting"><span class="keyword">template</span> <span class="special">&lt;</span><span class="keyword">class</span> <span class="identifier">T</span><span class="special">&gt;</span>
<a class="link" href="../result_type.html" title="Calculation of the Type of the Result"><span class="emphasis"><em>calculated-result-type</em></span></a> <span class="identifier">erf_inv</span><span class="special">(</span><span class="identifier">T</span> <span class="identifier">z</span><span class="special">);</span>

<span class="keyword">template</span> <span class="special">&lt;</span><span class="keyword">class</span> <span class="identifier">T</span><span class="special">,</span> <span class="keyword">class</span> <a class="link" href="../../policy.html" title="Chapter 22. Policies: Controlling Precision, Error Handling etc">Policy</a><span class="special">&gt;</span>
<a class="link" href="../result_type.html" title="Calculation of the Type of the Result"><span class="emphasis"><em>calculated-result-type</em></span></a> <span class="identifier">erf_inv</span><span class="special">(</span><span class="identifier">T</span> <span class="identifier">z</span><span class="special">,</span> <span class="keyword">const</span> <a class="link" href="../../policy.html" title="Chapter 22. Policies: Controlling Precision, Error Handling etc">Policy</a><span class="special">&amp;);</span>
</pre>
<p>
        Returns the <a href="http://functions.wolfram.com/GammaBetaErf/InverseErf/" target="_top">inverse
        error function</a> of z, that is a value x such that:
      </p>
<div class="blockquote"><blockquote class="blockquote"><p>
          <span class="serif_italic"><span class="emphasis"><em>p = erf(x);</em></span></span>
        </p></blockquote></div>
<div class="blockquote"><blockquote class="blockquote"><p>
          <span class="inlinemediaobject"><img src="../../../graphs/erf_inv.svg" align="middle"></span>

        </p></blockquote></div>
<pre class="programlisting"><span class="keyword">template</span> <span class="special">&lt;</span><span class="keyword">class</span> <span class="identifier">T</span><span class="special">&gt;</span>
<a class="link" href="../result_type.html" title="Calculation of the Type of the Result"><span class="emphasis"><em>calculated-result-type</em></span></a> <span class="identifier">erfc_inv</span><span class="special">(</span><span class="identifier">T</span> <span class="identifier">z</span><span class="special">);</span>

<span class="keyword">template</span> <span class="special">&lt;</span><span class="keyword">class</span> <span class="identifier">T</span><span class="special">,</span> <span class="keyword">class</span> <a class="link" href="../../policy.html" title="Chapter 22. Policies: Controlling Precision, Error Handling etc">Policy</a><span class="special">&gt;</span>
<a class="link" href="../result_type.html" title="Calculation of the Type of the Result"><span class="emphasis"><em>calculated-result-type</em></span></a> <span class="identifier">erfc_inv</span><span class="special">(</span><span class="identifier">T</span> <span class="identifier">z</span><span class="special">,</span> <span class="keyword">const</span> <a class="link" href="../../policy.html" title="Chapter 22. Policies: Controlling Precision, Error Handling etc">Policy</a><span class="special">&amp;);</span>
</pre>
<p>
        Returns the inverse of the complement of the error function of z, that is
        a value x such that:
      </p>
<div class="blockquote"><blockquote class="blockquote"><p>
          <span class="serif_italic"><span class="emphasis"><em>p = erfc(x);</em></span></span>
        </p></blockquote></div>
<div class="blockquote"><blockquote class="blockquote"><p>
          <span class="inlinemediaobject"><img src="../../../graphs/erfc_inv.svg" align="middle"></span>

        </p></blockquote></div>
<h5>
<a name="math_toolkit.sf_erf.error_inv.h2"></a>
        <span class="phrase"><a name="math_toolkit.sf_erf.error_inv.accuracy"></a></span><a class="link" href="error_inv.html#math_toolkit.sf_erf.error_inv.accuracy">Accuracy</a>
      </h5>
<p>
        For types up to and including 80-bit long doubles the approximations used
        are accurate to less than ~ 2 epsilon. For higher precision types these functions
        have the same accuracy as the <a class="link" href="error_function.html" title="Error Function erf and complement erfc">forward
        error functions</a>.
      </p>
<div class="table">
<a name="math_toolkit.sf_erf.error_inv.table_erf_inv"></a><p class="title"><b>Table 8.30. Error rates for erf_inv</b></p>
<div class="table-contents"><table class="table" summary="Error rates for erf_inv">
<colgroup>
<col>
<col>
<col>
<col>
<col>
</colgroup>
<thead><tr>
<th>
              </th>
<th>
                <p>
                  GNU C++ version 7.1.0<br> linux<br> double
                </p>
              </th>
<th>
                <p>
                  GNU C++ version 7.1.0<br> linux<br> long double
                </p>
              </th>
<th>
                <p>
                  Sun compiler version 0x5150<br> Sun Solaris<br> long double
                </p>
              </th>
<th>
                <p>
                  Microsoft Visual C++ version 14.1<br> Win32<br> double
                </p>
              </th>
</tr></thead>
<tbody><tr>
<td>
                <p>
                  Inverse Erf Function
                </p>
              </td>
<td>
                <p>
                  <span class="blue">Max = 0ε (Mean = 0ε)</span>
                </p>
              </td>
<td>
                <p>
                  <span class="blue">Max = 0.996ε (Mean = 0.389ε)</span>
                </p>
              </td>
<td>
                <p>
                  <span class="blue">Max = 1.08ε (Mean = 0.395ε)</span>
                </p>
              </td>
<td>
                <p>
                  <span class="blue">Max = 1.09ε (Mean = 0.502ε)</span>
                </p>
              </td>
</tr></tbody>
</table></div>
</div>
<br class="table-break"><div class="table">
<a name="math_toolkit.sf_erf.error_inv.table_erfc_inv"></a><p class="title"><b>Table 8.31. Error rates for erfc_inv</b></p>
<div class="table-contents"><table class="table" summary="Error rates for erfc_inv">
<colgroup>
<col>
<col>
<col>
<col>
<col>
</colgroup>
<thead><tr>
<th>
              </th>
<th>
                <p>
                  GNU C++ version 7.1.0<br> linux<br> double
                </p>
              </th>
<th>
                <p>
                  GNU C++ version 7.1.0<br> linux<br> long double
                </p>
              </th>
<th>
                <p>
                  Sun compiler version 0x5150<br> Sun Solaris<br> long double
                </p>
              </th>
<th>
                <p>
                  Microsoft Visual C++ version 14.1<br> Win32<br> double
                </p>
              </th>
</tr></thead>
<tbody>
<tr>
<td>
                <p>
                  Inverse Erfc Function
                </p>
              </td>
<td>
                <p>
                  <span class="blue">Max = 0ε (Mean = 0ε)</span>
                </p>
              </td>
<td>
                <p>
                  <span class="blue">Max = 0.996ε (Mean = 0.397ε)</span>
                </p>
              </td>
<td>
                <p>
                  <span class="blue">Max = 1.08ε (Mean = 0.403ε)</span>
                </p>
              </td>
<td>
                <p>
                  <span class="blue">Max = 1ε (Mean = 0.491ε)</span>
                </p>
              </td>
</tr>
<tr>
<td>
                <p>
                  Inverse Erfc Function: extreme values
                </p>
              </td>
<td>
              </td>
<td>
                <p>
                  <span class="blue">Max = 1.62ε (Mean = 0.383ε)</span>
                </p>
              </td>
<td>
                <p>
                  <span class="blue">Max = 1.62ε (Mean = 0.383ε)</span>
                </p>
              </td>
<td>
              </td>
</tr>
</tbody>
</table></div>
</div>
<br class="table-break"><p>
        The following error plot are based on an exhaustive search of the functions
        domain, MSVC-15.5 at <code class="computeroutput"><span class="keyword">double</span></code>
        precision, and GCC-7.1/Ubuntu for <code class="computeroutput"><span class="keyword">long</span>
        <span class="keyword">double</span></code> and <code class="computeroutput"><span class="identifier">__float128</span></code>.
      </p>
<div class="blockquote"><blockquote class="blockquote"><p>
          <span class="inlinemediaobject"><img src="../../../graphs/erfc__double.svg" align="middle"></span>

        </p></blockquote></div>
<div class="blockquote"><blockquote class="blockquote"><p>
          <span class="inlinemediaobject"><img src="../../../graphs/erfc__80_bit_long_double.svg" align="middle"></span>

        </p></blockquote></div>
<div class="blockquote"><blockquote class="blockquote"><p>
          <span class="inlinemediaobject"><img src="../../../graphs/erfc____float128.svg" align="middle"></span>

        </p></blockquote></div>
<h5>
<a name="math_toolkit.sf_erf.error_inv.h3"></a>
        <span class="phrase"><a name="math_toolkit.sf_erf.error_inv.testing"></a></span><a class="link" href="error_inv.html#math_toolkit.sf_erf.error_inv.testing">Testing</a>
      </h5>
<p>
        There are two sets of tests:
      </p>
<div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; ">
<li class="listitem">
            Basic sanity checks attempt to "round-trip" from <span class="emphasis"><em>x</em></span>
            to <span class="emphasis"><em>p</em></span> and back again. These tests have quite generous
            tolerances: in general both the error functions and their inverses change
            so rapidly in some places that round tripping to more than a couple of
            significant digits isn't possible. This is especially true when <span class="emphasis"><em>p</em></span>
            is very near one: in this case there isn't enough "information content"
            in the input to the inverse function to get back where you started.
          </li>
<li class="listitem">
            Accuracy checks using high-precision test values. These measure the accuracy
            of the result, given <span class="emphasis"><em>exact</em></span> input values.
          </li>
</ul></div>
<h5>
<a name="math_toolkit.sf_erf.error_inv.h4"></a>
        <span class="phrase"><a name="math_toolkit.sf_erf.error_inv.implementation"></a></span><a class="link" href="error_inv.html#math_toolkit.sf_erf.error_inv.implementation">Implementation</a>
      </h5>
<p>
        These functions use a rational approximation <a class="link" href="../sf_implementation.html#math_toolkit.sf_implementation.rational_approximations_used">devised
        by JM</a> to calculate an initial approximation to the result that is
        accurate to ~10<sup>-19</sup>, then only if that has insufficient accuracy compared
        to the epsilon for T, do we clean up the result using <a href="http://en.wikipedia.org/wiki/Simple_rational_approximation" target="_top">Halley
        iteration</a>.
      </p>
<p>
        Constructing rational approximations to the erf/erfc functions is actually
        surprisingly hard, especially at high precision. For this reason no attempt
        has been made to achieve 10<sup>-34 </sup> accuracy suitable for use with 128-bit reals.
      </p>
<p>
        In the following discussion, <span class="emphasis"><em>p</em></span> is the value passed to
        erf_inv, and <span class="emphasis"><em>q</em></span> is the value passed to erfc_inv, so that
        <span class="emphasis"><em>p = 1 - q</em></span> and <span class="emphasis"><em>q = 1 - p</em></span> and in
        both cases we want to solve for the same result <span class="emphasis"><em>x</em></span>.
      </p>
<p>
        For <span class="emphasis"><em>p &lt; 0.5</em></span> the inverse erf function is reasonably
        smooth and the approximation:
      </p>
<div class="blockquote"><blockquote class="blockquote"><p>
          <span class="serif_italic"><span class="emphasis"><em>x = p(p + 10)(Y + R(p))</em></span></span>
        </p></blockquote></div>
<p>
        Gives a good result for a constant Y, and R(p) optimised for low absolute
        error compared to |Y|.
      </p>
<p>
        For q &lt; 0.5 things get trickier, over the interval <span class="emphasis"><em>0.5 &gt;
        q &gt; 0.25</em></span> the following approximation works well:
      </p>
<div class="blockquote"><blockquote class="blockquote"><p>
          <span class="serif_italic"><span class="emphasis"><em>x = sqrt(-2log(q)) / (Y + R(q))</em></span></span>
        </p></blockquote></div>
<p>
        While for q &lt; 0.25, let
      </p>
<div class="blockquote"><blockquote class="blockquote"><p>
          <span class="serif_italic"><span class="emphasis"><em>z = sqrt(-log(q))</em></span></span>
        </p></blockquote></div>
<p>
        Then the result is given by:
      </p>
<div class="blockquote"><blockquote class="blockquote"><p>
          <span class="serif_italic"><span class="emphasis"><em>x = z(Y + R(z - B))</em></span></span>
        </p></blockquote></div>
<p>
        As before Y is a constant and the rational function R is optimised for low
        absolute error compared to |Y|. B is also a constant: it is the smallest
        value of <span class="emphasis"><em>z</em></span> for which each approximation is valid. There
        are several approximations of this form each of which reaches a little further
        into the tail of the erfc function (at <code class="computeroutput"><span class="keyword">long</span>
        <span class="keyword">double</span></code> precision the extended exponent
        range compared to <code class="computeroutput"><span class="keyword">double</span></code> means
        that the tail goes on for a very long way indeed).
      </p>
</div>
<div class="copyright-footer">Copyright © 2006-2021 Nikhar Agrawal, Anton Bikineev, Matthew Borland,
      Paul A. Bristow, Marco Guazzone, Christopher Kormanyos, Hubert Holin, Bruno
      Lalande, John Maddock, Evan Miller, Jeremy Murphy, Matthew Pulver, Johan Råde,
      Gautam Sewani, Benjamin Sobotta, Nicholas Thompson, Thijs van den Berg, Daryle
      Walker and Xiaogang Zhang<p>
        Distributed under the Boost Software License, Version 1.0. (See accompanying
        file LICENSE_1_0.txt or copy at <a href="http://www.boost.org/LICENSE_1_0.txt" target="_top">http://www.boost.org/LICENSE_1_0.txt</a>)
      </p>
</div>
<hr>
<div class="spirit-nav">
<a accesskey="p" href="error_function.html"><img src="../../../../../../doc/src/images/prev.png" alt="Prev"></a><a accesskey="u" href="../sf_erf.html"><img src="../../../../../../doc/src/images/up.png" alt="Up"></a><a accesskey="h" href="../../index.html"><img src="../../../../../../doc/src/images/home.png" alt="Home"></a><a accesskey="n" href="../sf_poly.html"><img src="../../../../../../doc/src/images/next.png" alt="Next"></a>
</div>
</body>
</html>
